[chain-pr 3/10] DatadogCore: CoreMessageBus implementation and rename#2929
[chain-pr 3/10] DatadogCore: CoreMessageBus implementation and rename#2929maxep wants to merge 4 commits into
Conversation
This comment has been minimized.
This comment has been minimized.
12f8b82 to
e2c1a49
Compare
ed91047 to
2469c47
Compare
e2c1a49 to
eebd698
Compare
2469c47 to
588136c
Compare
eebd698 to
0d4a09e
Compare
588136c to
c482945
Compare
0d4a09e to
9abfa86
Compare
9c99efb to
219583e
Compare
c482945 to
c2710e2
Compare
c2710e2 to
bf59182
Compare
…orTests.swift to Xcode project
12483fe to
39dd976
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 39dd976cf5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // forward any context change on the message-bus | ||
| self.contextProvider.publish { [weak self] context in | ||
| self?.send(message: .context(context)) | ||
| self?.bus.send(message: context) // typed bus (new receivers) |
There was a problem hiding this comment.
Replay initial context on the typed bus
This forwards only future context writes to typed subscribers, but registration still replays the current context only through add(messageReceiver:), which sends .context to the feature's legacy messageReceiver. The two migrated subscribers are now registered with NOPFeatureMessageReceiver() in CrossPlatformExtension and register(urlSessionHandler:), so if shared-context or network instrumentation is registered after user/RUM/trace context already exists, their typed receivers start with nil/stale context until another context mutation occurs; early shared-context callbacks and intercepted requests will miss that context.
Useful? React with 👍 / 👎.
| let contextSharingTransformer = ContextSharingTransformer() | ||
| try? core.register(feature: ContextSharingFeature(messageReceiver: contextSharingTransformer)) | ||
| // Subscribe before registration so initial context push is received: | ||
| core.messageBus.subscribe(receiver: contextSharingTransformer) |
There was a problem hiding this comment.
Unsubscribe shared context from the bus
Because MessageBus.subscribe(receiver:) retains the receiver until unsubscribe(receiver:), this added subscription survives unsubscribeFromSharedContext(): that method only cancels the callback and clears the static reference, while the registered feature now holds only a NOPFeatureMessageReceiver. In apps that unsubscribe and later resubscribe the cross-platform bridge, each cycle leaves another ContextSharingTransformer retained and processing every context update, so the documented drop of the subscription leaks work and memory unless the receiver is removed from the bus.
Useful? React with 👍 / 👎.
| } | ||
| } | ||
|
|
||
| extension CoreMessageBus: @retroactive Telemetry { |
There was a problem hiding this comment.
Is this conformance redundant? CoreMessageBus already conforms to Telemetry:
What and why?
The typed
MessageBusprotocol introduced in PR #2927 and the test infrastructure added in PR #2928 are ready, but the productionMessageBusclass inDatadogCorestill only implements the legacyFeatureMessagedispatch path. UntilCoreMessageBusimplements the typed protocol, no production code can route messages through the new typed bus.This PR is the core implementation layer: it renames the internal
MessageBusclass toCoreMessageBusto free the protocol name, implements the typedMessageBusprotocol on it with a bucket-based dispatch table, wiresDatadogCoreto expose it via themessageBusproperty, and migrates the twoDatadogContextreceivers (ContextSharingTransformerandNetworkContextCoreProvider) from the legacyFeatureMessageReceiverinterface to the typedBusMessageReceiver.How?
MessageBus.swift→CoreMessageBus.swift— typed protocol implementationCoreMessageBusgains a keyed dispatch table and a fullMessageBusconformance:receivers: [String: [ObjectIdentifier: Dispatch]]BusMessage.key; inner key is the receiver's object identity. Only receivers registered for a given message kind are iterated on dispatch.subscribe<Receiver>(receiver:)BusMessageReceiver; captures it strongly in aDispatchclosure. Re-subscribing replaces the previous entry.unsubscribe<Receiver>(receiver:)send<Message>(message:else:).configurationtelemetry for the existing deferred-accumulation path. Callsfallbackwhen the core is nil or the bucket is empty.Configuration telemetry is still intercepted before bucket dispatch to preserve the existing deferred-accumulation behaviour, and the legacy
FeatureMessagepath is kept for receivers that haven't migrated yet:DatadogCore— expose the typed busDatadogCorerenames itsbusproperty type fromMessageBus(the old class, nowCoreMessageBus) and exposes the typed bus throughDatadogCoreProtocol:Context updates are now routed through the typed bus:
ContextSharingTransformerandNetworkContextCoreProvider— typed-bus migrationBoth
DatadogContextreceivers are migrated fromFeatureMessageReceivertoBusMessageReceiver:ContextSharingTransformerFeatureMessageReceiver— switches on.contextBusMessageReceiver<DatadogContext>— receives typed context directlyNetworkContextCoreProviderFeatureMessageReceiver— guards on.contextBusMessageReceiver<DatadogContext>— receives typed context directlyReview checklist
make api-surfacewhen adding new APIsChain overview
graph LR G1["1 — Typed MessageBus protocol and shared message types"] G2["2 — Test infrastructure for typed message bus"] G3["3 — DatadogCore: CoreMessageBus implementation and rename"] G4["4 — DatadogCrashReporting: typed-bus migration"] G5["5 — DatadogLogs: typed-bus migration"] G6["6 — DatadogTrace: typed-bus migration"] G7["7 — DatadogFlags: typed-bus migration"] G8["8 — DatadogRUM: typed-bus migration and TelemetryInterceptor merge"] G9["9 — DatadogSessionReplay and DatadogWebViewTracking: typed-bus migration"] G10["10 — Documentation updates"] G1 --> G2 G2 --> G3 G3 --> G4 G3 --> G5 G5 --> G6 G3 --> G7 G6 --> G8 G7 --> G8 G8 --> G9 G1 --> G10Merge in dependency order. PRs with no incoming edges from un-merged PRs can be reviewed in parallel.